import getLastEvent from "./utils/getLastEvent";
import getSelector from "./getSelector";
import getStackLines from "./getStackLines";
import tracker from "./utils/tracker";

// js错误捕获
window.addEventListener(
  "error",
  function (event) {
    let lastEvent = getLastEvent();
    if (event.target && (event.target.src || event.target.href)) {
      tracker.send({
        kind: "stability", // 稳定性(大类)
        type: "error", // 小类（js error）
        errorType: "resourceError", // 资源加载错误
        tagName: event.target.tagName, // 报错标签
        filename: event.target.src || event.target.href, // 报错文件
        selector: getSelector(event.target), // 最后一个操作的元素
      });
    } else {
      tracker.send({
        kind: "stability", // 稳定性(大类)
        type: "error", // 小类（js error）
        errorType: "jsError", // JS执行错误
        message: event.message, // 报错信息
        filename: event.filename, // 报错文件
        position: `${event.lineno}:${event.colno}`, // 报错位置 行：列
        stack: getStackLines(event.error.stack),
        selector: lastEvent ? getSelector(lastEvent.path) : "", // 最后一个操作的元素
      });
    }
  },
  true
);

// promise错误捕获
window.addEventListener(
  "unhandledrejection",
  function (event) {
    let lastEvent = getLastEvent();
    let message;
    let filename;
    let lineno = 0;
    let colno = 0;
    let stack = "";
    let reason = event.reason;
    if (typeof reason === "string") {
      message = reason;
    } else if (typeof reason === "object") {
      message = reason.message;
      if (reason.stack) {
        let matchResult = reason.stack.match(/at\s+(.+):(\d+):(\d+)/);
        filename = matchResult[1];
        lineno = matchResult[2];
        colno = matchResult[3];
      }
      stack = getStackLines(reason.stack);
    }
    tracker.send({
      kind: "stability", // 稳定性(大类)
      type: "error", // 小类（js error）
      errorType: "promiseError", // JS执行错误
      message, // 报错信息
      filename, // 报错文件
      position: `${lineno}:${colno}`, // 报错位置 行：列
      stack,
      selector: lastEvent ? getSelector(lastEvent.path) : "", // 最后一个操作的元素
    });
  },
  true
);
